package com.ztman.rxjava.server.retrofit;

import com.orhanobut.logger.Logger;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.CacheControl;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import com.ztman.rxjava.MyApplication;
import com.ztman.rxjava.model.baseEntity.BaseUrl;
import com.ztman.rxjava.server.apiServer.SelfApi;
import com.ztman.rxjava.server.apiServer.UploadFileApi;
import com.ztman.rxjava.server.apiServer.WeatherApi;
import com.ztman.rxjava.utils.IfNetConnected;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

import retrofit.GsonConverterFactory;
import retrofit.Retrofit;
import retrofit.RxJavaCallAdapterFactory;

import static com.ztman.rxjava.utils.IfNetConnected.isConnected;

/**
 * Created by YJH on 2017/11/29.
 * 功能：进行网络请求的数据引擎类
 */

public class RetrofitService {
    //数据缓存大小的上限
    public static final long CATCHE_SIZE = 60 * 1000 * 1000;

    //设置缓存的有效时间为期 3 天/单位是秒
    public static final long CATCHE_EXIST_SECOND = 3 * 24 * 60 * 60;

    //查询缓存的Cache-Control设置，为if-only-cache时只查询缓存而不会请求服务器，max-stale可以配合设置缓存失效时间
    protected static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CATCHE_EXIST_SECOND;

    //查询网络的Cache-Control设置，头部Cache-Control设为max-age=0时则不会使用缓存而请求服务器
    protected static final String CACHE_CONTROL_NETWORK = "max-age=0";

    private static OkHttpClient mOkHttpClient;

    private RetrofitService() {
    }


    //单列
    private volatile static RetrofitService instance = null;

    public static RetrofitService getInstance() {
        if (instance == null) {
            synchronized (RetrofitService.class) {
                if (instance == null) {
                    instance = new RetrofitService();
                }
            }
        }
        return instance;
    }


    /**
     * 功能：根据网络状况-获取缓存的策略
     */
    public String getCacheControl() {
        return IfNetConnected.isConnected(MyApplication.getContext()) ? CACHE_CONTROL_NETWORK : CACHE_CONTROL_CACHE;
    }

    /**
     * 功能初始化-设置 OkHttpClient
     */
    private void initOkHttpClientMethod() {
        if (null == mOkHttpClient) {

            //指定 缓存的路径
            File catcheFile = new File(MyApplication.getContext().getCacheDir(), "request_cache_dir");

            //制定 数据缓存大小的上限
            Cache cache = new Cache(catcheFile, CATCHE_SIZE);

            Interceptor interceptor = new Interceptor() {
                @Override
                public Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();

                    //网络未连接
                    if (!isConnected(MyApplication.getContext())) {
                        Logger.e("功能初始化-设置 OkHttpClient-出现了网络未连接");
                        request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
                    }
                    Response response = chain.proceed(request);

                    //有网时,在读接口上的@Headers中的配置，可以在这里进行统一的设置
                    //就是设置请求网络还是读取缓存
                    if (isConnected(MyApplication.getContext())) {
                        String cacheControl = request.cacheControl().toString();
                        return response.newBuilder()
                                .header("Cache-Control", cacheControl)
                                .removeHeader("Pragma").build();
                    } else {
                        return response.newBuilder().header("Cache-Control",
                                "public, only-if-cached," + CATCHE_EXIST_SECOND)
                                .removeHeader("Pragma").build();
                    }

                }
            };

            mOkHttpClient = new OkHttpClient();
            mOkHttpClient.setCache(cache);
            mOkHttpClient.networkInterceptors().add(interceptor);
            mOkHttpClient.interceptors().add(interceptor);
            mOkHttpClient.setConnectTimeout(20, TimeUnit.SECONDS);//就设置20秒

        }
    }



    //POST:获取个人资料
    private SelfApi mSelfApi = null;
    public SelfApi createSelfApi(){
        if (mSelfApi == null) {
            synchronized (RetrofitService.class) {
                if (mSelfApi == null) {
                    initOkHttpClientMethod();
                    mSelfApi = new Retrofit.Builder()
                            .client(mOkHttpClient)
                            .baseUrl(BaseUrl.selfBase)
                            .addConverterFactory(GsonConverterFactory.create())
                            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                            .build().create(SelfApi.class);
                }
            }
        }
        return mSelfApi;
    }

    //POST:文件上传
    private UploadFileApi mUploadFileApi = null;
    public UploadFileApi createUploadFileApi(){
        if (mUploadFileApi == null) {
            synchronized (RetrofitService.class) {
                if (mUploadFileApi == null) {
                    initOkHttpClientMethod();
                    mUploadFileApi = new Retrofit.Builder()
                            .client(mOkHttpClient)
                            .baseUrl(BaseUrl.selfBase)
                            .addConverterFactory(GsonConverterFactory.create())
                            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                            .build().create(UploadFileApi.class);
                }
            }
        }
        return mUploadFileApi;
    }

    //GET:获取北京的天气信息
    private WeatherApi mWeatherApi = null;
    public WeatherApi createWeatherApi(){
        if (mWeatherApi == null) {
            synchronized (RetrofitService.class) {
                if (mWeatherApi == null) {
                    initOkHttpClientMethod();
                    mWeatherApi = new Retrofit.Builder()
                            .client(mOkHttpClient)
                            .baseUrl(BaseUrl.weatherBase)
                            .addConverterFactory(GsonConverterFactory.create())
                            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                            .build().create(WeatherApi.class);
                }
            }
        }
        return mWeatherApi;
    }








}
